package com.example.model.interceptor;

import com.example.model.pojo.User;
import com.example.model.utils.JwtUtils;
import com.example.model.utils.UserHolder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;

/**
 * 登录拦截器，用于验证用户身份和权限
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LoginInterceptor implements HandlerInterceptor {

    private final JwtUtils jwtUtils;
    private static final String BEARER_PREFIX = "Bearer ";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 记录请求日志
        log.debug("拦截请求: {}, 方法: {}", request.getRequestURI(), request.getMethod());

        try {
            // 获取Authorization请求头
            String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);


            if (authorization == null || !authorization.startsWith(BEARER_PREFIX)) {
                log.warn("请求缺少有效的Authorization头: {}", request.getRequestURI());
                return handleUnauthorized(response, "未提供身份认证信息");
            }

            // 提取token
            String token = authorization.substring(BEARER_PREFIX.length());
            log.debug("提取到token: {}", maskToken(token));

            // 验证token有效性
            if (!jwtUtils.validateToken(token)) {
                log.warn("无效的token: {}", maskToken(token));
                return handleUnauthorized(response, "身份认证信息无效");
            }

            // 解析token，获取用户信息
            User user = new User();
            user.setId(jwtUtils.getUserIdFromToken(token));
            user.setName(jwtUtils.getUserNameFromToken(token));
            user.setRole(jwtUtils.getUserRoleFromToken(token));
            
            // 将用户信息保存到ThreadLocal
            UserHolder.set(user);

            // 检查权限（可根据需要扩展）
            if (!checkPermission(request, user)) {
                log.warn("用户权限不足: userId={}, 请求: {}", user.getId(), request.getRequestURI());
                return handleForbidden(response, "权限不足，无法访问该资源");
            }

            return true;
        } catch (RuntimeException e) {
            log.error("JWT验证异常: {}", e.getMessage());
            return handleUnauthorized(response, "身份认证信息已过期或无效");
        } catch (Exception e) {
            log.error("身份验证过程中发生异常: {}", e.getMessage(), e);
            return handleUnauthorized(response, "身份验证失败");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理用户登录信息，防止内存泄漏
        UserHolder.remove();
        log.debug("清理用户登录信息: {}", request.getRequestURI());
    }

    /**
     * 处理未授权的请求
     */
    private boolean handleUnauthorized(HttpServletResponse response, String message) throws Exception {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(String.format("{\"code\": 401, \"message\": \"%s\", \"data\": null}", message));
        writer.flush();
        writer.close();
        return false;
    }

    /**
     * 处理权限不足的请求
     */
    private boolean handleForbidden(HttpServletResponse response, String message) throws Exception {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(String.format("{\"code\": 403, \"message\": \"%s\", \"data\": null}", message));
        writer.flush();
        writer.close();
        return false;
    }

    /**
     * 检查用户是否有权限访问资源
     * 可根据实际业务需求扩展权限检查逻辑
     */
    private boolean checkPermission(HttpServletRequest request, User user) {
        String uri = request.getRequestURI();
        Integer role = user.getRole();

        // 示例权限检查：教师可以访问所有资源，学生只能访问特定资源
        // 这里可以根据项目需求实现更复杂的权限检查逻辑
        if (role == 1) { // 教师角色
            return true;
        } else if (role == 0) { // 学生角色
            // 学生只能访问特定的API路径
            return uri.startsWith("/user/") || 
                   uri.startsWith("/student-selection/") ||
                   uri.startsWith("/report/");
        }

        return false;
    }

    /**
     * 掩码处理token，用于日志记录
     */
    private String maskToken(String token) {
        if (token.length() <= 8) {
            return "***";
        }
        return token.substring(0, 4) + "***" + token.substring(token.length() - 4);
    }
}
